#include "StdAfx.h"
//-------------------------------------------------------------------------------------------------
//ProcParamsDefs.cpp  - Collection of Parameter Definitions for an Image Processing Step       
//-------------------------------------------------------------------------------------------------
//FreeBSD License
//Copyright 2012 Will Stott All rights reserved.
//
//Redistribution and use in source and binary forms, with or without modification, are
//permitted provided that the following conditions are met:
//
//   1. Redistributions of source code must retain the above copyright notice, this list of
//      conditions and the following disclaimer.
//
//   2. Redistributions in binary form must reproduce the above copyright notice, this list
//      of conditions and the following disclaimer in the documentation and/or other materials
//      provided with the distribution.
//
//THIS SOFTWARE IS PROVIDED BY Will Stott ``AS IS'' AND ANY EXPRESS OR IMPLIED
//WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
//FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Will Stott OR
//CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
//SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
//ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
//ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//The views and conclusions contained in the software and documentation are those of the
//authors and should not be interpreted as representing official policies, either expressed
//or implied, of Will Stott.
//
//----Authors--------------------------------------------------------------------------------------
//created by: will.stott@ucl.ac.uk Feb 2012
//
//----Comments-------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------
#include "ImageExptLib.h"
#include "ImageProcStepLibAuto.h"

#include "ProcParamsDefs.h"
#include "ProcParamsOutputs.h"
#include "ProcParamsInputs.h"


ProcParamsDefs::ProcParamsDefs(void) :
	_error(true)
{

}


ProcParamsDefs::~ProcParamsDefs(void)
{
	ClearParams();
}

bool	ProcParamsDefs::Validate()
{
	bool rc = false;

	if( _Params.size() < 1 )
		ImageExptLib::LogMsg("ProcParamsDefs::Validate", "ERROR: No Params found");
	else
	{
		if (IsIndexSeqComplete(IPluginICProcStepsParamDef::input) == false)	//has it a consecutive set of index values for both in/out 0,1,2,...?
			ImageExptLib::LogMsg("ProcParamsDefs::Validate", "ERROR: input params list does not have a set of consecutive indexes");
		else
		{
			if (IsIndexSeqComplete(IPluginICProcStepsParamDef::output) == false)
				ImageExptLib::LogMsg("ProcParamsDefs::Validate", "ERROR: output params list does not have a set of consecutive indexes");
			else
			{											//has it an Result output parameter?
				ProcParamDef *def = GetDef(IPluginICProcStepsParamAttribOutputNameResult);
				if ( (def == '\0') || (def->GetDirection() != IPluginICProcStepsParamDef::output))
					ImageExptLib::LogMsg("ProcParamsDefs::Validate", "ERROR: mandatory output param <%s> not found", IPluginICProcStepsParamAttribOutputNameResult);
				else
					rc = true;
			}
		}
	}
	_error = (rc == true) ? false : true;
	return rc;	
}

bool	ProcParamsDefs::IsMatch(ProcParamsOutputs *outputs, ProcParamsInputs *inputs)
{
	bool rc = false;

	if (IsValid() == false)
		ImageExptLib::LogMsg("ProcParamsDefs::IsMatch", "ERROR: Params to check against are not valid");
	else
	{
		if (outputs == '\0')
			ImageExptLib::LogMsg("ProcParamsDefs::IsMatch", "ERROR: outputs is null");	
		else
		{		
			if (inputs == '\0')	
				ImageExptLib::LogMsg("ProcParamsDefs::IsMatch", "ERROR: inputs is null");
			else
			{
				int cntO = GetParamDefCount(IPluginICProcStepsParamDef::output);
				int cntI = GetParamDefCount(IPluginICProcStepsParamDef::input);

				if(outputs->GetParamCount() != cntO)
					ImageExptLib::LogMsg("ProcParamsDefs::IsMatch", "ERROR: passed outputs param cnt %d != ProcParamsDefs output param cnt %d", outputs->GetParamCount(), cntO);				
				else
				{
					if (inputs->GetParamCount() != cntI)
						ImageExptLib::LogMsg("ProcParamsDefs::IsMatch", "ERROR: passed inputs param cnt %d != ProcParamsDefs input param cnt %d", inputs->GetParamCount(), cntI);	
					else
					{
						if (IsMatchByDirection(outputs, cntO, IPluginICProcStepsParamDef::output))
						{
							if (IsMatchByDirection(inputs, cntI, IPluginICProcStepsParamDef::input))
								rc = true;
						}
					}
				}
			}
		}
	}
	return rc;
}

bool	ProcParamsDefs::AddParamDef(ProcParamDef *proc)
{
	bool rc = false;

	if (proc == '\0') 
		ImageExptLib::LogMsg("ProcParamsDefs::AddParamDef", "ERROR: Input Param is null");
	else
	{
		if (proc->IsValid() == false)
			ImageExptLib::LogMsg("ProcParamsDefs::AddParamDef", "ERROR: %s Param (%s) not valiated", ((proc->GetDirection() == IPluginICProcStepsParamDef::input) ? "in" : "out"), proc->GetName());
		else
		{
			if ( GetParamDef(proc->GetName()) != '\0')								//parameter names are unique
				ImageExptLib::LogMsg("ProcParamsDefs::AddParamDef", "ERROR: %s Param (%s) already present", ((proc->GetDirection() == IPluginICProcStepsParamDef::input) ? "in" : "out"), proc->GetName());
			else
			{
				if ( GetParamDef(proc->GetIndex(), proc->GetDirection()) != '\0')	//index values are unique for inputs or outputs
					ImageExptLib::LogMsg("ProcParamsDefs::AddParamDef", "ERROR: %s Param (%s) index=%d already present", ((proc->GetDirection() == IPluginICProcStepsParamDef::input) ? "in" : "out"), proc->GetName(), proc->GetIndex());
				else
				{
					_Params.push_back(proc);
					_error = true;					//must eventually validate this collection of parameters to check that they form a valid set; i.e. have a result, no missing indexs, etc
					rc = true;
				}
			}
		}
	}
	return rc;
}

int	ProcParamsDefs::GetParamDefCount()
{ 
	int rc = ProcParamsDefs::InvalidCount;

	if (IsValid() == false)
		ImageExptLib::LogMsg("ProcParamsDefs::GetParamDef(name)", "ERROR: Params not valiated");		
	else
		rc = static_cast<int>(_Params.size()); 
	return rc;
}

ProcParamDef *	ProcParamsDefs::GetParamDef(const char *ParamName)
{
	ProcParamDef *rc = '\0';

	if ( IsValid() == false)
		ImageExptLib::LogMsg("ProcParamsDefs::GetParamDef(name)", "ERROR: Params not valiated");
	else
		rc = GetDef(ParamName);

	return rc;
}

ProcParamDef *ProcParamsDefs::GetParamDef(int index, IPluginICProcStepsParamDef::Direction io)
{
	ProcParamDef *rc = '\0';

	if ( IsValid() == false)
		ImageExptLib::LogMsg("ProcParamsDefs::GetParamDef(index)", "ERROR: Params not valiated");
	else
		rc = GetDef(index, io);

	return rc;
}

int	ProcParamsDefs::GetParamDefCount(IPluginICProcStepsParamDef::Direction io)
{
	int	rc = ProcParamsDefs::InvalidCount;

	if ( IsValid() == false)
		ImageExptLib::LogMsg("ProcParamsDefs::GetParamDefCount", "ERROR: Params not valiated");
	else
		rc = GetParamCount(io);

	return rc;
}


int	ProcParamsDefs::GetIndex(const char *ParamName)
{
	int rc = IPluginICProcStepsParamDef::NotFound;

	if ( IsValid() == false)
		ImageExptLib::LogMsg("ProcParamsDefs::GetIndex", "ERROR: Params not valiated");
	else
	{
		if (ParamName == '\0')
			ImageExptLib::LogMsg("ProcParamsDefs::GetIndex", "ERROR: Input Param is null");
		else
		{
			std::string paramName(ParamName);
			size_t cnt = _Params.size();
			for (size_t pos = 0; pos < cnt; pos++)
			{
				ProcParamDef *def = _Params[pos];
				if (def == '\0')
					ImageExptLib::LogMsg("ProcParamsDefs::GetIndex", "ERROR: Param=%d is null", (int)pos);
				else
				{
					if (paramName == def->GetName())
					{
						rc = def->GetIndex();
						break;
					}
				}
			}
		}
	}
	return rc;
}

ProcParamDef *ProcParamsDefs::GetParamDefByPosition(int pos)
{ 
	ProcParamDef *rc = '\0';

	if ( IsValid() == false)
		ImageExptLib::LogMsg("ProcParamsDefs::GetParamDefByPosition", "ERROR: Params not valiated");
	else
	{
		int cnt = GetParamDefCount();
		if ((pos >= cnt) || (pos < 0))
			ImageExptLib::LogMsg("ProcParamsDefs::GetParamDefByPosition", "ERROR: invalid param pos=%d for params=%d", pos, cnt);
		else
			rc = _Params[pos];
	}
	return rc;
}

bool ProcParamsDefs::ClearParams()
{
	bool rc = false;

	size_t cnt = _Params.size();
	if (cnt > 0 )
	{
		for (size_t pos = 0; pos < cnt; pos++)
			delete  _Params[pos];
		_Params.clear();
		rc = true;
	}
	_error = true;
	return rc;
}

//-------------------------------------------------------------------------------------------------
//			PRIVATE
//-------------------------------------------------------------------------------------------------

bool	ProcParamsDefs::IsIndexSeqComplete(IPluginICProcStepsParamDef::Direction io)
{
	bool rc = true;

	int cnt = GetParamCount(io);
	for (int index = 0; index < cnt; index++ )
	{
		if (GetDef(index, io) == '\0')
		{
			ImageExptLib::LogMsg("ProcParamsDefs::IsIndexSeqComplete()", "ERROR: %s param(%d) not found", ((io == IPluginICProcStepsParamDef::input) ? "input" : "output"), index);
			rc = false;
			break;
		}
	}
	return rc;
}

bool	ProcParamsDefs::IsMatchByDirection(ProcParams* params, int cnt, IPluginICProcStepsParamDef::Direction dir)
{
	bool rc = true;

	for (int index = 0; index < cnt; index++ )
	{
		ProcParamDef *def = GetDef(index, dir);
		if (def == '\0')
		{
			ImageExptLib::LogMsg("ProcParamsDefs::IsMatchByDirection()", "ERROR: ProcParamsDefs %s param(%d) not found", ((dir == IPluginICProcStepsParamDef::input) ? "input" : "output"), index);
			rc = false;
		}
		else
		{
			ProcParam *param = params->GetParam(index);
			if (param == '\0')
			{
				ImageExptLib::LogMsg("ProcParamsDefs::IsMatchByDirection()", "ERROR: passed %s param(%d) not found", ((dir == IPluginICProcStepsParamDef::input) ? "input" : "output"), index);
				rc = false;
			}
			else
			{
//wpqs				if (def->IsMatch(param, dir) == false)
//				{
					ImageExptLib::LogMsg("ProcParamsDefs::IsMatchByDirection()", "ERROR: %s param %s->IsMatch() () failed", ((dir == IPluginICProcStepsParamDef::input) ? "input" : "output"), param->GetName());
//					rc = false;
//				}
			}
		}
		if ( rc == false)
			break;
	}
	return rc;
}

ProcParamDef *	ProcParamsDefs::GetDef(const char *ParamName)
{
	ProcParamDef *rc = '\0';

	int pos = IPluginICProcStepsParamDef::NotFound;
	if ( (pos = GetPosition(ParamName)) != IPluginICProcStepsParamDef::NotFound)
		rc = _Params[pos];

	return rc;
}

ProcParamDef *ProcParamsDefs::GetDef(int index, IPluginICProcStepsParamDef::Direction io)
{
	ProcParamDef *rc = '\0';

	size_t cnt = _Params.size();
	for (size_t pos = 0; pos < cnt; pos++)
	{
		ProcParamDef *def = _Params[pos];
		if (def == '\0')
			ImageExptLib::LogMsg("ProcParamsDefs::GetDef", "ERROR: Param=%d is null", (int)pos);
		else
		{
			if ((index == def->GetIndex()) && (io == def->GetDirection()))
			{
				rc = def;
				break;
			}
		}
	}
	return rc;
}

int	ProcParamsDefs::GetPosition(const char *ParamName)
{
	int rc = IPluginICProcStepsParamDef::NotFound;

	if (ParamName != '\0')
	{
		std::string paramName(ParamName);
		size_t cnt = _Params.size();
		for (size_t pos = 0; pos < cnt; pos++)
		{
			ProcParamDef *def = _Params[pos];
			if (def == '\0')
				ImageExptLib::LogMsg("ProcParamsDefs::GetPosition", "ERROR: Param=%d is null", (int)pos);
			else
			{
				if (paramName == def->GetName())
				{
					rc = pos;
					break;
				}
			}
		}
	}
	return rc;
}

int	ProcParamsDefs::GetParamCount(IPluginICProcStepsParamDef::Direction io)
{
	int	rc = 0;

	size_t cnt = _Params.size();
	for (size_t pos = 0; pos < cnt; pos++)
	{
		ProcParamDef *def = _Params[pos];
		if (def == '\0')
			ImageExptLib::LogMsg("ProcParamsDefs::GetParamCount", "ERROR: Param=%d is null", (int)pos);
		else
		{
			if (io == def->GetDirection())
				rc++;
		}
	}
	return rc;
}


//-------------------------------------------------------------------------------------------------
//			E N D   O F   F I L E
//-------------------------------------------------------------------------------------------------
